﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Collections.Specialized;
using System.ComponentModel;
using System.Reflection;
using System.Data;

namespace Tools.Other
{
    public static class ObjectExtension
    {
        /// <summary>
        ///     获取枚举变量值的 Description 属性
        /// </summary>
        /// <param name="obj">枚举变量</param>
        /// <returns>如果包含 Description 属性，则返回 Description 属性的值，否则返回枚举变量值的名称</returns>
        public static string GetDescription(this object obj)
        {
            return GetDescription(obj, false);
        }


        /// <summary>
        ///     获取枚举变量值的 Description 属性
        /// </summary>
        /// <param name="obj">枚举变量</param>
        /// <param name="isTop">是否改变为返回该类、枚举类型的头 Description 属性，而不是当前的属性或枚举变量值的 Description 属性</param>
        /// <returns>如果包含 Description 属性，则返回 Description 属性的值，否则返回枚举变量值的名称</returns>
        public static string GetDescription(this object obj, bool isTop)
        {
            if (obj == null)
            {
                return string.Empty;
            }

            try
            {
                Type enumType = obj.GetType();
                DescriptionAttribute dna = null;

                if (isTop)
                {
                    dna = (DescriptionAttribute)Attribute.GetCustomAttribute(enumType, typeof(DescriptionAttribute));
                }

                else
                {
                    FieldInfo fi = enumType.GetField(Enum.GetName(enumType, obj));
                    dna = (DescriptionAttribute)Attribute.GetCustomAttribute(
                        fi, typeof(DescriptionAttribute));
                }

                if (dna != null && string.IsNullOrEmpty(dna.Description) == false)
                    return dna.Description;
            }
            catch (Exception)
            {
            }

            return obj.ToString();
        }

        public static string ToJson(this object Msg)
        {
            return JsonHelper.ToJson(Msg);
         

        }

        /// <summary>
        /// 根据枚举类型返回类型中的所有值，及描述
        /// </summary>
        /// <param name="type"></param>
        /// <param name="not">不包含那些项：eg,"back|Pass"</param>
        /// <returns>返回List{Value,Text}</returns>
        public static Dictionary<string, string> GetEnumList(this Type type, string not = "")
        {

            Dictionary<string, string> itemlist = new Dictionary<string, string>();
            FieldInfo[] fields = type.GetFields();
            for (int i = 1, count = fields.Length; i < count; i++)
            {
                string[] strEnum = new string[3];
                FieldInfo field = fields[i];
                //值列
                strEnum[0] = ((int)Enum.Parse(type, field.Name)).ToString();
                //文本列赋值
                strEnum[2] = field.Name;

                object[] objs = field.GetCustomAttributes(typeof(DescriptionAttribute), false);
                if (objs == null || objs.Length == 0)
                {
                    strEnum[1] = field.Name;
                }
                else
                {
                    DescriptionAttribute da = (DescriptionAttribute)objs[0];
                    strEnum[1] = da.Description;
                }

                if (!not.Contains(strEnum[1]))
                {
                    itemlist.Add(strEnum[0], strEnum[1]);
                }

            }
            return itemlist;
        }

        /// <summary>
        ///     实体对象初始化
        /// </summary>
        /// <param name="model">实体对象</param>
        /// <param name="nv">实体属性值集合,name value </param>
        public static void MapProperties(this NameValueCollection nv, object model)
        {
            PropertyInfo[] properties = model.GetType().GetProperties();

            string[] keys = nv.AllKeys;

            for (int i = 0; i < keys.Length; i++)
            {
                foreach (var p in properties)
                {
                    //if (keys[i].Replace("_", string.Empty).ToLower().Equals( p.Name.ToLower())) //加'_'符号，支持直接以数据表字段命控件
                    //{
                    //    if (!p.PropertyType.Name.Contains("Nullable"))
                    //    {

                    //        object value = Convert.ChangeType(nv[keys[i]].Trim().Replace("script", "!script").Replace("!!", "!"), p.PropertyType);
                    //        p.SetValue(model, value, null);
                    //    }
                    //    else
                    //    {
                    //        object value = string.IsNullOrEmpty(nv[keys[i]].Trim())
                    //                           ? null
                    //                           : Convert.ChangeType(nv[keys[i]].Trim().Replace("script", "!script").Replace("!!", "!"),
                    //                                                Nullable.GetUnderlyingType(p.PropertyType));
                    //        p.SetValue(model, value, null);
                    //    }


                    //    break;
                    //}
                    if (keys[i].ToLower().Equals(p.Name.ToLower())) //加'_'符号，支持直接以数据表字段命控件
                    {
                        if (!p.PropertyType.Name.Contains("Nullable"))
                        {

                            object value = Convert.ChangeType(nv[keys[i]].Trim().Replace("script", "!script").Replace("!!", "!"), p.PropertyType);
                            p.SetValue(model, value, null);
                        }
                        else
                        {
                            object value = string.IsNullOrEmpty(nv[keys[i]].Trim())
                                               ? null
                                               : Convert.ChangeType(nv[keys[i]].Trim().Replace("script", "!script").Replace("!!", "!"),
                                                                    Nullable.GetUnderlyingType(p.PropertyType));
                            p.SetValue(model, value, null);
                        }


                        break;
                    }
                }
            }
        }

      
       
      
        public static string FirstToUpper(this string field, bool isConvert)
        {
            string chStr = field;
            if (!isConvert)
                return chStr;

            if (field.Length > 0)
            {
                chStr = field.Substring(0, 1).ToUpper() + field.Substring(1).ToLower();
            }
            return chStr;

        }

       

      
       

        /// <summary>
        ///     实体对象初始化
        /// </summary>
        /// <param name="dataTable">Data数据表 </param>
        public static List<T> ToList<T>(this DataTable dataTable) where T : new()
        {
            List<T> lstEntity = new List<T>();
            T entity = new T();
            PropertyInfo[] properties = entity.GetType().GetProperties();

            DataColumnCollection dcc = dataTable.Columns;

            foreach (DataRow dr in dataTable.Rows)
            {
                T model = new T();
                for (int cx = 0; cx < dcc.Count; cx++)
                {
                    foreach (var p in properties)
                    {
                        if (dcc[cx].ColumnName.ToLower() == p.Name.ToLower())
                        {
                            string strValue = dr[cx].ToString().Trim();
                            //dr[cx].ToString().Trim().Replace("script", "!script").Replace("!!", "!")
                            if (!p.PropertyType.Name.Contains("Nullable"))
                            {
                                //不能为空的字段
                                object value = Convert.ChangeType(strValue, p.PropertyType);
                                p.SetValue(model, value, null);
                            }
                            else
                            {
                                object value = string.IsNullOrEmpty(dr[cx].ToString())
                                                   ? null
                                                   : Convert.ChangeType(strValue,
                                                                        Nullable.GetUnderlyingType(p.PropertyType));
                                p.SetValue(model, value, null);
                            }


                            break;
                        }
                    }

                }

                lstEntity.Add(model);

            }

            return lstEntity;
        }
        /// <summary>
        /// 将列表扩展为DataTable
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="items"></param>
        /// <returns></returns>
        public static DataTable ToDataTable<T>(this List<T> items)
        {
            DataTable dataTable = new DataTable(typeof(T).Name);

            PropertyInfo[] Props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
            foreach (PropertyInfo prop in Props)
            {
                dataTable.Columns.Add(prop.Name);
            }
            foreach (T item in items)
            {
                var values = new object[Props.Length];
                for (int i = 0; i < Props.Length; i++)
                {

                    values[i] = Props[i].GetValue(item, null);
                }
                dataTable.Rows.Add(values);
            }

            return dataTable;
        }


        public static DataTable GetPagedTable(this DataTable dt, int PageIndex, int PageSize, out int AllRowsCount)
        {
            //PageCount = 0;
            AllRowsCount = 0;
            if (PageIndex == 0)
                return dt;
            DataTable newdt = dt.Copy();
            newdt.Clear();

            int rowbegin = (PageIndex - 1) * PageSize;
            int rowend = PageIndex * PageSize;

            if (rowbegin >= dt.Rows.Count)
                return newdt;

            if (rowend > dt.Rows.Count)
                rowend = dt.Rows.Count;
            for (int i = rowbegin; i <= rowend - 1; i++)
            {
                DataRow newdr = newdt.NewRow();
                DataRow dr = dt.Rows[i];
                foreach (DataColumn column in dt.Columns)
                {
                    newdr[column.ColumnName] = dr[column.ColumnName];
                }
                newdt.Rows.Add(newdr);
            }

            AllRowsCount = dt.Rows.Count;
            //计算总页数 beg
            //int page = dt.Rows.Count / PageSize;
            //if (dt.Rows.Count % PageSize > 0)
            //{
            //    page = page + 1;
            //}
            //PageCount = page;
            //计算总页数 end
            return newdt;
        }

     


        public static bool dsIsNullOrEmpty(this DataSet ds)
        {
            if (ds != null && ds.Tables != null && ds.Tables[0].Rows.Count > 0)
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        public static bool dtIsNullOrEmpty(this DataTable dt)
        {
            if (dt != null && dt.Rows.Count > 0)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
        //public static DataRow GetSumRow(this DataTable dt, string sumColumn)
        //{
        //    DataRow dr = dt.NewRow();
        //    string[] sumColumns = sumColumn.Split(',');
        //    //var dt_Enumerable = dt.AsEnumerable();

        //    //Type t = dt.Columns.GetType();

        //    foreach (string str in sumColumns)
        //    {
        //        object o = dt.Compute("sum(" + str + ")", "");
        //        dr[str] = o;
        //        //object sumC = dt_Enumerable.Sum(sumCol => sumCol.Field<decimal>(str));
        //    }

        //    return dr;
        //}
    }
}
